﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace TurnamentOrganizer
{
    public partial class NextRoundForm : Form
    {
        Tournament _main;

        public NextRoundForm(Tournament main)
        {
            InitializeComponent();
            this._main = main;
            InitializeDataGrid();
            
            dataGridViewMatches.BindingContext = new BindingContext();

            if (_main.roundNo == 1)
            {
                dataGridViewMatches.DataSource = MatchPlayersFirstRound();
            }
            else
            {
                dataGridViewMatches.DataSource = MatchPlayers();
            }

            _main.roundNo++;            
        }

        private void InitializeDataGrid()
        {
            dataGridViewMatches.AutoGenerateColumns = false;

            DataGridViewTextBoxColumn tableCol = new DataGridViewTextBoxColumn();
            tableCol.DataPropertyName = "_tableNo";
            tableCol.HeaderText = "Bord";

            dataGridViewMatches.Columns.Add(tableCol);

            DataGridViewTextBoxColumn player1Col = new DataGridViewTextBoxColumn();
            player1Col.DataPropertyName = "_player1";
            player1Col.HeaderText = "Spiller 1";

            dataGridViewMatches.Columns.Add(player1Col);

            DataGridViewTextBoxColumn player2Col = new DataGridViewTextBoxColumn();
            player2Col.DataPropertyName = "_player2";
            player2Col.HeaderText = "Spiller 2";

            dataGridViewMatches.Columns.Add(player2Col);
        }

        /// <summary>
        /// Find a list of eligible opponents for this specific player.
        /// In the first round, this is only based on the player's home location
        /// </summary>
        private List<Match> MatchPlayersFirstRound()
        {
            //Create a list of players not matched (yet)
            List<Player> playersNotMatched = _main.playerList.ToList();
            List<Player> eligiblePlayers = new List<Player>();
            List<Match> matches = new List<Match>();
            Player selectedPlayer;
            Player selectedOpponent = null;
            Match match;
            int currentTableNo = 1;
            Random rand = new Random();
            int selectedOpponentNo;

            int locationCount;
            int locationCountMax;
            string mostCommonLocation = "";

            do
            {
                //Find the most common home location
                locationCount = 0;
                locationCountMax = 0;

                foreach (var location in _main.Locations)
                {
                    locationCount = playersNotMatched.Count(player => player.HomeLocation == location);

                    if (locationCount > locationCountMax)
                    {
                        locationCountMax = locationCount;
                        mostCommonLocation = location;
                    }
                }                                

                //Select the first remaining player in the list 
                selectedPlayer = playersNotMatched.First(player => player.HomeLocation == mostCommonLocation);

                //Find all players where player's homelocation is not equal to the current selected player's homelocation 
                //eligiblePlayers = playersNotMatched.Where(Players => Players.HomeLocation != selectedPlayer.HomeLocation).ToList();

                eligiblePlayers = (from player in playersNotMatched
                                  where player.HomeLocation != selectedPlayer.HomeLocation
                                  select player).ToList();

                //If there's only players left from the same location, choose a random one from the ones remaining
                if (eligiblePlayers.Count == 0)
                {
                    selectedOpponentNo = rand.Next(0, playersNotMatched.Count());
                    selectedOpponent = playersNotMatched[selectedOpponentNo];
                }
                else //There's at least one eligible player, select one of them.
                {                    
                    selectedOpponentNo = rand.Next(0, eligiblePlayers.Count());
                    selectedOpponent = eligiblePlayers[selectedOpponentNo];
                }
                
                match = new Match(selectedPlayer, selectedOpponent, currentTableNo);

                matches.Add(match);

                //Remove the players from the 'not matched' list, the players have been matched
                playersNotMatched.Remove(selectedPlayer);
                playersNotMatched.Remove(selectedOpponent);

                //And select the next table
                currentTableNo++;
            } while (playersNotMatched.Count > 0);

            return matches;
        }

        private List<Match> MatchPlayers()
        {
            List<Player> playersNotMatched = _main.playerList.ToList();
            List<Player> eligiblePlayers = new List<Player>();
            List<Match> matches = new List<Match>();
            Match match;            
            int currentTableNo = 1;

            //Find and sort all players
            eligiblePlayers = (from players in playersNotMatched                               
                               orderby players.ControlPoints descending
                               orderby players.Wins descending
                               select players).ToList();

            //Create matches
            for (int i = 0; i < eligiblePlayers.Count; i += 2)
            {
                match = new Match(eligiblePlayers[i], eligiblePlayers[i + 1], currentTableNo);
                matches.Add(match);
            }
            
            return matches;
        }
    }
}
